﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;


namespace ConstantCMapEditor3
{
    public class IntelligentTexture
    {
        public static ResourceEntry[] ResourceEntryData = new ResourceEntry[]
        {
                //hand write
                new ResourceEntry("BackGround_2","BackGround_2",0,0,1890,1344),
                new ResourceEntry("BackGround_3","BackGround_3",0,0,1086,756),
                new ResourceEntry("BackGround_MainMenu","BackGround_MainMenu",0,0,1280,960),
                new ResourceEntry("BackGround_S10","BackGround_S10",0,0,2048,1641),
                new ResourceEntry("BackGround_S12","BackGround_S12",0,0,1512,1701),
                new ResourceEntry("BackGround_S13","BackGround_S13",0,0,2024,1236),
                new ResourceEntry("BackGround_S14","BackGround_S14",0,0,1790,1245),
                new ResourceEntry("BackGround_S15","BackGround_S15",0,0,1076,1648),
                new ResourceEntry("BackGround_S16","BackGround_S16",0,0,2047,1835),
                new ResourceEntry("BackGround_S17","BackGround_S17",0,0,1890,1890),
                new ResourceEntry("BackGround_S18","BackGround_S18",0,0,1555,1163),
                new ResourceEntry("BackGround_S19","BackGround_S19",0,0,1890,1512),
                new ResourceEntry("BackGround_S20","BackGround_S20",0,0,1209,1983),
                new ResourceEntry("BackGround_S21","BackGround_S21",0,0,1081,2048),
                new ResourceEntry("BackGround_S22","BackGround_S22",0,0,1512,1134),
                new ResourceEntry("BackGround_S23","BackGround_S23",0,0,1889,1398),
                new ResourceEntry("BackGround_S24","BackGround_S24",0,0,1435,878),
                new ResourceEntry("BackGround_S25","BackGround_S25",0,0,1947,1259),
                new ResourceEntry("BackGround_S26","BackGround_S26",0,0,2044,1492),
                new ResourceEntry("BackGround_S27","BackGround_S27",0,0,1890,1512),
                new ResourceEntry("BackGround_S3","BackGround_S3",0,0,2047,1797),
                new ResourceEntry("BackGround_S4_1","BackGround_S4_1",0,0,1007,1020),
                new ResourceEntry("BackGround_S4_2","BackGround_S4_2",0,0,1260,1020),
                new ResourceEntry("BackGround_S5","BackGround_S5",0,0,1323,1323),
                new ResourceEntry("BackGround_S6","BackGround_S6",0,0,1890,1707),
                new ResourceEntry("BackGround_S7","BackGround_S7",0,0,1890,1512),
                new ResourceEntry("BackGround_S8","BackGround_S8",0,0,1890,1890),
                new ResourceEntry("BackGround_S9","BackGround_S9",0,0,1512,1512),
                new ResourceEntry("BackGround_T1","BackGround_T1",0,0,1512,1134),
                new ResourceEntry("BackGround_T2","BackGround_T2",0,0,945,1701),
                new ResourceEntry("Roller_1","Roller_1",0,0,1086,756),
                new ResourceEntry("White","White",0,0,1,1),
                //hand write

                //MenuBackGound
                new ResourceEntry("BDSLogo","MenuBackGround",2,484,984,1024),
                new ResourceEntry("BigMenuWorld1","MenuBackGround",988,484,973,480),
                new ResourceEntry("BigMenuWorld2","MenuBackGround",2,1510,1077,480),
                new ResourceEntry("BigMenuWorld3","MenuBackGround",2,2,1077,480),
                new ResourceEntry("Form1","MenuBackGround",1081,2,720,180),
                new ResourceEntry("logo_1","MenuBackGround",1333,1626,250,130),
                new ResourceEntry("logo_2","MenuBackGround",1585,1494,250,130),
                new ResourceEntry("logo_3","MenuBackGround",1333,1494,250,130),
                new ResourceEntry("logo_S10","MenuBackGround",1744,966,250,130),
                new ResourceEntry("logo_S12","MenuBackGround",1492,966,250,130),
                new ResourceEntry("logo_S13","MenuBackGround",1240,1362,250,130),
                new ResourceEntry("logo_S14","MenuBackGround",1240,1230,250,130),
                new ResourceEntry("logo_S15","MenuBackGround",1240,1098,250,130),
                new ResourceEntry("logo_S16","MenuBackGround",1240,966,250,130),
                new ResourceEntry("logo_S17","MenuBackGround",1081,1890,250,130),
                new ResourceEntry("logo_S18","MenuBackGround",1081,1758,250,130),
                new ResourceEntry("logo_S19","MenuBackGround",1081,1626,250,130),
                new ResourceEntry("logo_S20","MenuBackGround",1081,1494,250,130),
                new ResourceEntry("logo_S21","MenuBackGround",988,1362,250,130),
                new ResourceEntry("logo_S22","MenuBackGround",988,1230,250,130),
                new ResourceEntry("logo_S23","MenuBackGround",988,1098,250,130),
                new ResourceEntry("logo_S24","MenuBackGround",988,966,250,130),
                new ResourceEntry("logo_S25","MenuBackGround",1586,184,250,130),
                new ResourceEntry("logo_S26","MenuBackGround",1585,316,250,130),
                new ResourceEntry("logo_S27","MenuBackGround",1334,184,250,130),
                new ResourceEntry("logo_S3","MenuBackGround",1744,1362,250,130),
                new ResourceEntry("logo_S4","MenuBackGround",1492,1362,250,130),
                new ResourceEntry("logo_S5","MenuBackGround",1744,1230,250,130),
                new ResourceEntry("logo_S6","MenuBackGround",1081,184,251,130),
                new ResourceEntry("logo_S7","MenuBackGround",1492,1230,250,130),
                new ResourceEntry("logo_S8","MenuBackGround",1744,1098,250,130),
                new ResourceEntry("logo_S9","MenuBackGround",1492,1098,250,130),
                new ResourceEntry("logo_T1","MenuBackGround",1333,316,250,130),
                new ResourceEntry("logo_T2","MenuBackGround",1081,316,250,130),
                //MenuBackGound
            

                //InGameTexture
                new ResourceEntry("ActionButton","InGameTexture",2,620,574,82),
                new ResourceEntry("BackToMenu","InGameTexture",358,704,218,65),
                new ResourceEntry("Black","InGameTexture",980,100,32,32),
                new ResourceEntry("DeathNeedle","InGameTexture",986,604,23,62),
                new ResourceEntry("Door","InGameTexture",498,840,58,81),
                new ResourceEntry("Exit","InGameTexture",174,1025,120,60),
                new ResourceEntry("FanInside","InGameTexture",904,140,60,60),
                new ResourceEntry("FanOutside","InGameTexture",904,78,60,60),
                new ResourceEntry("FormPanel","InGameTexture",578,668,430,299),
                new ResourceEntry("JumpButton","InGameTexture",2,990,170,85),
                new ResourceEntry("JumpButtonGrey","InGameTexture",904,289,85,85),
                new ResourceEntry("LeftButton","InGameTexture",2,903,170,85),
                new ResourceEntry("LeftButtonGrey","InGameTexture",904,202,85,85),
                new ResourceEntry("Light","InGameTexture",983,2,38,38),
                new ResourceEntry("Panel2","InGameTexture",2,2,979,74),
                new ResourceEntry("Player","InGameTexture",2,78,900,540),
                new ResourceEntry("PlayerGravityLight","InGameTexture",296,840,200,200),
                new ResourceEntry("RedLight","InGameTexture",983,42,35,56),
                new ResourceEntry("RedLightGlow","InGameTexture",296,1042,150,150),
                new ResourceEntry("ResetButton","InGameTexture",300,771,257,67),
                new ResourceEntry("ReturnButton","InGameTexture",2,724,296,70),
                new ResourceEntry("RightButton","InGameTexture",2,1077,170,85),
                new ResourceEntry("RightButtonGrey","InGameTexture",904,376,85,85),
                new ResourceEntry("SoundButton","InGameTexture",2,796,210,105),
                new ResourceEntry("box-01","InGameTexture",174,903,120,120),
                new ResourceEntry("box-03","InGameTexture",214,796,80,80),
                new ResourceEntry("breakStone","InGameTexture",904,545,80,80),
                new ResourceEntry("breakStonePiece","InGameTexture",986,530,32,16),
                new ResourceEntry("face_circle_big","InGameTexture",498,969,160,160),
                new ResourceEntry("face_circle_mid","InGameTexture",904,463,80,80),
                new ResourceEntry("mainBody1","InGameTexture",597,650,17,8),
                new ResourceEntry("mainBody2","InGameTexture",578,650,17,8),
                new ResourceEntry("mainHand1","InGameTexture",966,95,12,15),
                new ResourceEntry("mainHand2","InGameTexture",966,78,14,15),
                new ResourceEntry("mainHead","InGameTexture",986,580,24,22),
                new ResourceEntry("mainLeg1","InGameTexture",708,627,17,20),
                new ResourceEntry("mainLeg2","InGameTexture",1000,158,21,14),
                new ResourceEntry("moving_bar","InGameTexture",708,649,132,17),
                new ResourceEntry("moving_bar_b","InGameTexture",2,704,354,18),
                new ResourceEntry("moving_bar_bv","InGameTexture",1000,174,18,354),
                new ResourceEntry("moving_bar_v","InGameTexture",559,771,17,132),
                new ResourceEntry("particle_fire","InGameTexture",966,168,32,32),
                new ResourceEntry("particle_point","InGameTexture",966,134,32,32),
                new ResourceEntry("particle_small_point","InGameTexture",1000,134,22,22),
                new ResourceEntry("safe","InGameTexture",578,627,128,21),
                new ResourceEntry("smallGear","InGameTexture",986,548,30,30),


                 //InGameTexture

                 //Menu
                new ResourceEntry("Menu","Menu",2,2,720,480),
                new ResourceEntry("SmallYellowgear","Menu",252,484,40,40),
                new ResourceEntry("StartButton","Menu",646,733,120,120),
                new ResourceEntry("Yellowgear","Menu",520,592,139,139),
                new ResourceEntry("globalBall","Menu",2,566,258,258),
                new ResourceEntry("lockedSpot","Menu",64,484,45,40),
                new ResourceEntry("return","Menu",2,484,60,60),
                new ResourceEntry("smallWorld1","Menu",520,484,200,106),
                new ResourceEntry("startArrow","Menu",436,824,208,149),
                new ResourceEntry("world1","Menu",262,566,256,256),
                new ResourceEntry("world1OpenSpot","Menu",111,484,45,40),
                new ResourceEntry("world2-stone","Menu",724,2,280,280),
                new ResourceEntry("world2","Menu",724,284,280,280),
                new ResourceEntry("world2OpenSpot","Menu",205,484,45,40),
                new ResourceEntry("world3-stone","Menu",2,826,215,196),
                new ResourceEntry("world3","Menu",219,826,215,195),
                new ResourceEntry("world3OpenSpot","Menu",158,484,45,40),
                //Menu


                new ResourceEntry("upArrowG","upArrowG",0,0,50,46),
                new ResourceEntry("leftArrow","leftArrow",0,0,50,46),
                new ResourceEntry("rightArrow","rightArrow",0,0,50,46),
                new ResourceEntry("downArrow","downArrow",0,0,50,46),
                new ResourceEntry("EnterButton","EnterButton",0,0,77,44),
                new ResourceEntry("AButton","AButton",0,0,50,46),
                new ResourceEntry("SButton","SButton",0,0,50,46),
                new ResourceEntry("DButton","DButton",0,0,50,46),
                new ResourceEntry("WButton","WButton",0,0,50,46),
                new ResourceEntry("SpaceButton","SpaceButton",0,0,249,55),
                new ResourceEntry("MonsterBlackHole","MonsterBlackHole",0,0,32,32),
                new ResourceEntry("Particle005","Particle005",0,0,128,128),
                new ResourceEntry("pathPoint","pathPoint",0,0,10,10),
                new ResourceEntry("CD","CD",0,0,32,35),
                new ResourceEntry("GravityButton","GravityButton",0,0,18,48),

                new ResourceEntry("buffer-02","buffer-02",0,0,25,19),
                new ResourceEntry("NextDoor","NextDoor",0,0,86,87),
                new ResourceEntry("bigball","bigball",0,0,158,158),
                new ResourceEntry("bigbox_02","bigbox_02",0,0,120,120),
                new ResourceEntry("ball","ball",0,0,80,80),
                new ResourceEntry("box","box",0,0,80,80),
                
                new ResourceEntry("lift","lift",0,0,131,13),
                new ResourceEntry("swingbar","swingbar",0,0,130,25),
                new ResourceEntry("FallBuffer","FallBuffer",0,0,128,25),
                new ResourceEntry("fan-01","fan-01",0,0,49,49),
                new ResourceEntry("bigswingbar","bigswingbar",0,0,354,24),

                 new ResourceEntry("lightSource","lightSource",0,0,10,18),
                new ResourceEntry("deathLaser","deathLaser",0,0,32,64),
                new ResourceEntry("death_electric_base","death_electric_base",0,0,32,64),
                new ResourceEntry("death_fire_base","death_fire_base",0,0,32,64),
                new ResourceEntry("death_fire","death_fire",0,0,32,64),
                new ResourceEntry("death_electric","death_electric",0,0,144,22),
                
                new ResourceEntry("death_gear","death_gear",0,0,64,64),
                new ResourceEntry("death_gear_black","death_gear_black",0,0,64,64),
                new ResourceEntry("death_gear_black2","death_gear_black2",0,0,64,64),
                new ResourceEntry("death_gear_light","death_gear_light",0,0,14,18),
        };

        public Texture2D Texture2D
        {
            get;
            set;
        }

        public Rectangle ResourceRectangle
        {
            get;
            set;
        }

        public static IntelligentTexture IntelligentLoad(String textureName)
        {
            foreach (ResourceEntry entry in ResourceEntryData)
            {
                if (entry._resourceName.Equals(textureName))
                {
                    Texture2D targetTexture = ResourceManager.LoadTexture2DContent(entry._resourceTexture);

                    IntelligentTexture data = new IntelligentTexture();
                    data.Texture2D = targetTexture;
                    data.ResourceRectangle = entry._resourceRectangle;
                    return data;
                }
            }
            throw new Exception("Target Resource Not Found : " + textureName);
        }

        //map Editor Only
        public static IntelligentTexture ConvertTexture2DToIntelligent(Texture2D texture2D) 
        {
            IntelligentTexture data = new IntelligentTexture();
            data.Texture2D = texture2D;
            data.ResourceRectangle = new Rectangle(0,0,texture2D.Width,texture2D.Height);
            return data;
        }
    }

    public class ResourceEntry
    {
        public ResourceEntry(String resoruceName, String resourceTexture, int x, int y, int width, int height)
        {
            _resourceName = resoruceName;
            _resourceTexture = resourceTexture;
            _resourceRectangle = new Rectangle(x, y, width, height);
        }

        public String _resourceName
        {
            get;
            set;
        }

        public String _resourceTexture
        {
            get;
            set;
        }

        public Rectangle _resourceRectangle
        {
            get;
            set;
        }
    }

    public class ResourceManager
    {
        static ContentManager _content;

        public static List<String> ResourceNameList = new List<String>();
        public static List<Texture2D> Texture2DList = new List<Texture2D>();
        public static List<System.Drawing.Image> BitmapList = new List<System.Drawing.Image>();
        public static List<String> ForBitmapNameList = new List<String>();

        public static List<SpriteFont> SpriteFontList = new List<SpriteFont>();
        public static List<String> ResourceFontNameList = new List<String>();

        public static IntelligentTexture IntelligentLoad(String textureName)
        {
            return IntelligentTexture.IntelligentLoad(textureName);
        }

        public static void Initialize(ContentManager content)
        {
            _content = new ContentManager(content.ServiceProvider, content.RootDirectory);
        }

        public static Texture2D LoadTexture2DContent(String target)
        {
            if (ResourceNameList.Contains(target))
            {
                int index = ResourceNameList.IndexOf(target);
                return Texture2DList[index];
            }
            else
            {
                Texture2D texture2D = _content.Load<Texture2D>(target);
                ResourceNameList.Add(target);
                Texture2DList.Add(texture2D);
                return texture2D;
            }
        }

        public static Texture2D LoadFromFileContent(String target) 
        {
            Texture2D texture;

            if (ResourceNameList.Contains(target))
            {
                int index = ResourceNameList.IndexOf(target);
                return Texture2DList[index];
            }
            else
            {
                using (Stream stream = File.OpenRead(target))
                {
                    texture = Texture2D.FromStream(Game1.GD, stream);
                  //  texture.Format = 9;
                    Color[] data = new Color[texture.Width* texture.Height];
                    texture.GetData(data);

                    for (int i = 0; i < texture.Width * texture.Height; i++)
                        data[i] = new Color(data[i].R / 255f * data[i].A / 255f, data[i].G / 255f * data[i].A / 255f, data[i].B / 255f * data[i].A / 255f, data[i].A / 255f);

                    texture.SetData(data);
                }

                ResourceNameList.Add(target);
                Texture2DList.Add(texture);
                return texture;
            }
        }

        public static System.Drawing.Image LoadBitmapFromFile(String target)
        {
            System.Drawing.Image bitmap;

            if (ForBitmapNameList.Contains(target))
            {
                int index = ResourceNameList.IndexOf(target);
                return BitmapList[index];
            }
            else
            {
                bitmap = System.Drawing.Bitmap.FromFile(target + ".png");
                ForBitmapNameList.Add(target);
                BitmapList.Add(bitmap);
                return bitmap;
            }
        }

        public static System.Drawing.Image ConvertTexture2DToImage(Texture2D texture)
        {
            byte[] textureData = new byte[4 * texture.Width * texture.Height];
            texture.GetData<Byte>(textureData);
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(texture.Width, texture.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, texture.Width, texture.Height),
                                                                     System.Drawing.Imaging.ImageLockMode.WriteOnly,
                                                                     System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            IntPtr safePtr = bmpData.Scan0;
            System.Runtime.InteropServices.Marshal.Copy(textureData, 0, safePtr, textureData.Length);
            bmp.UnlockBits(bmpData);

            return bmp;
        }

        public static System.Drawing.Image ConvertTexture2DToImage(Texture2D texture, Rectangle rec)
        {
            byte[] textureData = new byte[4 * texture.Width * texture.Height];
            byte[] newTextureData = new byte[4 * rec.Width * rec.Height];
            texture.GetData<Byte>(textureData);

            for (int i = 0; i < rec.Width; i++)
            {
                for (int j = 0; j < rec.Height; j++)
                {

                    newTextureData[4 * (j * rec.Width + i)] = textureData[4 * ((rec.Y + j) * texture.Width + rec.X + i) + 2];
                    newTextureData[4 * (j * rec.Width + i) + 1] = textureData[4 * ((rec.Y + j) * texture.Width + rec.X + i) + 1];
                    newTextureData[4 * (j * rec.Width + i) + 2] = textureData[4 * ((rec.Y + j) * texture.Width + rec.X + i) + 0];
                    newTextureData[4 * (j * rec.Width + i) + 3] = textureData[4 * ((rec.Y + j) * texture.Width + rec.X + i) + 3];
                }
            }

            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(rec.Width, rec.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, rec.Width, rec.Height),
                                                                     System.Drawing.Imaging.ImageLockMode.WriteOnly,
                                                                     System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            IntPtr safePtr = bmpData.Scan0;
            System.Runtime.InteropServices.Marshal.Copy(newTextureData, 0, safePtr, newTextureData.Length);
            bmp.UnlockBits(bmpData);

            return bmp;
        }

        public static SpriteFont LoadFontContent(String target)
        {
            if (ResourceFontNameList.Contains(target))
            {
                int index = ResourceFontNameList.IndexOf(target);
                return SpriteFontList[index];
            }
            else
            {
                SpriteFont font = _content.Load<SpriteFont>(target);
                ResourceFontNameList.Add(target);
                SpriteFontList.Add(font);
                return font;
            }
        }



        public static void UnloadAll()
        {
            _content.Unload();
            ResourceNameList.Clear();
            Texture2DList.Clear();
            SpriteFontList.Clear();
            ResourceFontNameList.Clear();

        }

        public static void UnloadTexture2DContent(String target)
        {
            //fill me
        }
    }
}
